home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / gfx / show / GS510_data.lha / ghostscript / 5.10 / gs_setpd.ps < prev    next >
Text File  |  1997-12-28  |  21KB  |  668 lines

  1. %    Copyright (C) 1994, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % The current implementation of setpagedevice has the following limitations:
  16. %    - It doesn't attempt to "interact with the user" for Policy = 2.
  17.  
  18. languagelevel 1 .setlanguagelevel
  19. level2dict begin
  20.  
  21. % ---------------- Redefinitions ---------------- %
  22.  
  23. % Redefine .beginpage and .endpage so that they call BeginPage and
  24. % EndPage respectively if appropriate.
  25.  
  26. % We have to guard against the BeginPage procedure not popping its operand.
  27. % This is really stupid, but the Genoa CET does it.
  28. /.beginpage        % - .beginpage -
  29.  { .currentshowpagecount
  30.     { .currentpagedevice pop /BeginPage .knownget
  31.        {    % Stack: ... pagecount proc
  32.      count 2 .execn
  33.         % Stack: ... ..???.. oldcount
  34.      count 1 add exch sub { pop } repeat
  35.        }
  36.        { pop
  37.        }
  38.       ifelse
  39.     }
  40.    if
  41.  } bind odef
  42.  
  43. % Guard similarly against EndPage not popping its operand.
  44. /.endpage        % <reason> .endpage <print_bool>
  45.  { .currentshowpagecount
  46.     { 1 index .currentpagedevice pop /EndPage .knownget
  47.        {    % Stack: ... reason pagecount reason proc
  48.      count 2 .execn
  49.         % Stack: ... ..???.. print oldcount
  50.      count 2 add exch sub { exch pop } repeat
  51.        }
  52.        { pop pop 2 ne
  53.        }
  54.       ifelse
  55.     }
  56.     { 2 ne
  57.     }
  58.    ifelse
  59.  } bind odef
  60.  
  61. % Define interpreter callouts for handling gstate-saving operators,
  62. % to make sure that they create a page device dictionary for use by
  63. % the corresponding gstate-restoring operator.
  64. % We'd really like to avoid the cost of doing this, but we don't see how.
  65. % The names %gsavepagedevice, %savepagedevice, %gstatepagedevice,
  66. % %copygstatepagedevice, and %currentgstatepagedevice are known to the
  67. % interpreter.
  68.  
  69. (%gsavepagedevice) cvn
  70.  { currentpagedevice pop gsave
  71.  } bind def
  72.  
  73. (%savepagedevice) cvn
  74.  { currentpagedevice pop save
  75.  } bind def
  76.  
  77. (%gstatepagedevice) cvn
  78.  { currentpagedevice pop gstate
  79.  } bind def
  80.  
  81. (%copygstatepagedevice) cvn
  82.  { currentpagedevice pop copy
  83.  } bind def
  84.  
  85. (%currentgstatepagedevice) cvn
  86.  { currentpagedevice pop currentgstate
  87.  } bind def
  88.  
  89. % Define interpreter callouts for handling gstate-restoring operators
  90. % when the current page device needs to be changed.
  91. % The names %grestorepagedevice, %grestoreallpagedevice,
  92. % %restorepagedevice, and %setgstatepagedevice are known to the interpreter.
  93.  
  94. /.installpagedevice
  95.  {    % Since setpagedevice doesn't create new device objects,
  96.     % we must (carefully) reinstall the old parameters in
  97.     % the same device.
  98.    .currentpagedevice pop null currentdevice null .trysetparams
  99.    dup type /booleantype eq
  100.     { pop pop }
  101.     {        % This should never happen!
  102.       DEBUG { (Error in .trysetparams!\n) print pstack flush } if
  103.       cleartomark pop pop pop
  104.       /.installpagedevice cvx /rangecheck signalerror
  105.     }
  106.    ifelse pop pop
  107.    erasepage initgraphics .beginpage
  108.  } bind def
  109.  
  110. /.uninstallpagedevice
  111.  { 2 .endpage { .currentnumcopies false .outputpage } if
  112.    nulldevice
  113.  } bind def
  114.  
  115. (%grestorepagedevice) cvn
  116.  { .uninstallpagedevice grestore .installpagedevice
  117.  } bind def
  118.  
  119. (%grestoreallpagedevice) cvn
  120.  { .uninstallpagedevice grestore .installpagedevice grestoreall
  121.  } bind def
  122.  
  123. (%restorepagedevice) cvn
  124.  { .uninstallpagedevice grestore .installpagedevice restore
  125.  } bind def
  126.  
  127. (%setgstatepagedevice) cvn
  128.  { .uninstallpagedevice setgstate .installpagedevice
  129.  } bind def
  130.  
  131. % Redefine .currentnumcopies so it consults the NumCopies device parameter.
  132. /.numcopiesdict mark
  133.   /NumCopies dup
  134. .dicttomark readonly def
  135.  
  136. /.currentnumcopies
  137.  { currentdevice //.numcopiesdict .getdeviceparams
  138.    dup type /integertype eq
  139.     { exch pop exch pop }
  140.     { cleartomark #copies }
  141.    ifelse
  142.  } bind odef
  143.  
  144. % ---------------- Auxiliary definitions ---------------- %
  145.  
  146. % Define the required attributes of all page devices, and their default values.
  147. % We don't include attributes such as .MediaSize, which all devices
  148. % are guaranteed to supply on their own.
  149. /.defaultpolicies mark
  150.   /PolicyNotFound 1
  151.   /PageSize 0
  152.   /PolicyReport {pop} bind
  153. .dicttomark readonly def
  154. /.requiredattrs mark
  155.   /PageOffset [0 0] readonly
  156. % We define InputAttributes and OutputAttributes with a single
  157. % dummy media type that handles pages of any size.
  158. % Devices that care will override this.
  159.   /InputAttributes mark 0
  160.     mark /PageSize [0 dup 16#7ffff dup] .dicttomark readonly
  161.   .dicttomark readonly
  162.   (%MediaSource) 0
  163.   /OutputAttributes mark 0
  164.     mark .dicttomark readonly
  165.   .dicttomark readonly
  166.   (%MediaDestination) 0
  167.   /Install {.callinstall} bind
  168.   /BeginPage {.callbeginpage} bind
  169.   /EndPage {.callendpage} bind
  170.   /Policies .defaultpolicies
  171. .dicttomark readonly def
  172.  
  173. % Define currentpagedevice so it creates the dictionary on demand if needed,
  174. % adding all the required entries defined just above.
  175. % We have to deal specially with entries that the driver may change
  176. % on its own.
  177. /.dynamicppkeys mark
  178.   /.MediaSize dup        % because it changes when PageSize is set
  179.   /PageCount dup
  180. .dicttomark readonly def
  181. /.makecurrentpagedevice        % - .makecurrentpagedevice <dict>
  182.  { currentdevice null .getdeviceparams
  183.     % In case of duplicate keys, .dicttomark takes the entry
  184.     % lower on the stack, so we can just append the defaults here.
  185.    .requiredattrs { } forall .dicttomark
  186.    dup .setpagedevice
  187.  } bind def
  188. /currentpagedevice
  189.  { .currentpagedevice
  190.     { dup length 0 eq
  191.        { pop .makecurrentpagedevice
  192.        }
  193.        {    % If any of the dynamic keys have changed,
  194.         % we must update the page device dictionary.
  195.      currentdevice //.dynamicppkeys .getdeviceparams .dicttomark
  196.       {    % Stack: current key value
  197.         2 index 2 index .knownget { 1 index ne } { true } ifelse
  198.          { 2 index wcheck not
  199.         {    % This is the first entry being updated.
  200.             % Copy the dictionary to make it writable.
  201.           3 -1 roll dup length dict .copydict
  202.           3 1 roll
  203.         }
  204.            if
  205.            2 index 3 1 roll put
  206.          }
  207.          { pop pop
  208.          }
  209.         ifelse
  210.       }
  211.      forall
  212.         % We would like to do a .setpagedevice so we don't keep
  213.         % re-creating the dictionary.  Unfortunately, the effect
  214.         % of this is that if any dynamic key changes (PageCount
  215.         % in particular), we will do the equivalent of a
  216.         % setpagedevice at the next restore or grestore.
  217.         % Therefore, we make the dictionary read-only, but
  218.         % we don't store it away.  I.e., NOT:
  219.         % dup wcheck { .setpagedevice .currentpagedevice pop } if
  220.      readonly
  221.        }
  222.       ifelse
  223.     }
  224.    if
  225.  } bind odef
  226.  
  227. % The implementation of setpagedevice is quite complex.  Currently,
  228. % everything but the media matching algorithm is implemented here.
  229.  
  230. % By default, we only present the requested changes to the device,
  231. % but there are some parameters that require special merging action.
  232. % Define those parameters here, with the procedures that do the merging.
  233. % The procedures are called as follows:
  234. %    <merged> <key> <new_value> -proc- <merged> <key> <new_value'>
  235. /.mergespecial mark
  236.   /InputAttributes
  237.    { dup null eq
  238.       { pop null
  239.       }
  240.       { 3 copy pop .knownget
  241.      { dup null eq
  242.         { pop dup length dict }
  243.         { dup length 2 index length add dict .copydict }
  244.        ifelse
  245.      }
  246.      { dup length dict
  247.      }
  248.         ifelse .copydict readonly
  249.       }
  250.      ifelse
  251.    } bind
  252.   /OutputAttributes 1 index
  253.   /Policies
  254.     { 3 copy pop .knownget
  255.        { dup length 2 index length add dict .copydict }
  256.        { dup length dict }
  257.       ifelse copy readonly
  258.     } bind
  259. .dicttomark readonly def
  260.  
  261. % Define the keys used in input attribute matching.
  262. /.inputattrk